package edu.mapi.ir.gui;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.util.prefs.Preferences;

import javax.swing.AbstractAction;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.UIManager;

import edu.mapi.ir.MazeWalker;
import edu.mapi.ir.StateListener;
import edu.mapi.ir.controllers.SimpleReactiveController;
import edu.mapi.ir.state.EstimatedMaze;
import edu.mapi.ir.state.EstimatedState;

/**
 * @author ZP
 */
public class MazeSlammer extends JFrame implements StateListener {

	private Preferences prefs = Preferences.systemNodeForPackage(MazeSlammer.class);
	private String host = prefs.get("host", "127.0.0.1");
	private EstimatedMaze estimatedMaze = new EstimatedMaze(this);
	private MazeWalker client;
	
	public MazeSlammer() {
		createMenus();
		setTitle("MazeSlammer");		
		setLayout(new BorderLayout(2,2));
		add(estimatedMaze, BorderLayout.CENTER);
		EstimatedState state = new EstimatedState();
		state.setX(EstimatedMaze.MAX_WIDTH/2);
		state.setY(EstimatedMaze.MAX_HEIGHT/2);
		state.setRotation(Math.PI/2);
		stateChanged(state);
	}
	
	private void createMenus() {
		JMenuBar menubar = new JMenuBar();
		
		JMenu file = new JMenu("File");
		
		AbstractAction connect = new AbstractAction("Connect...", GuiUtils.getIcon("imgs/start.png")) {
			public void actionPerformed(ActionEvent e) {
				String input = JOptionPane.showInputDialog(null, "Please provide the server hostname", "127.0.0.1");				
				if (input != null) {
					host = input;
					prefs.put("hostname", input);
					try {
						client = new MazeWalker();
						EstimatedState state = new EstimatedState();
							
						state.setX(EstimatedMaze.MAX_WIDTH/2);
						state.setY(EstimatedMaze.MAX_HEIGHT/2);
						state.setRotation(Math.PI/2);
						
						client.setState(state);										
						client.setActiveController(new SimpleReactiveController());
						stateChanged(state);

						client.addStateListener(MazeSlammer.this);
						client.start(host);	
					}
					catch (Exception ex) {
						client = null;
						repaint();						
						GuiUtils.errorMessage(MazeSlammer.this, "Error connecting to server", ex.getMessage());
					}
				}
			}
		};		
		file.add(connect);
		
		file.addSeparator();
		
		file.add(new AbstractAction("Exit", GuiUtils.getIcon("imgs/exit.png")) {
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});
		
		menubar.add(file);

		JMenu options = new JMenu("Options");
		
		options.add(new AbstractAction("Map Resolution") {
			public void actionPerformed(ActionEvent e) {
				String resp = JOptionPane.showInputDialog(MazeSlammer.this, "Change Map Resolution (cells per unit)", EstimatedMaze.RESOLUTION);
				if (resp == null)
					return;
				try {
					
					int res = Integer.parseInt(resp);
					if (res <= 0 || res >= 11) {
						throw new Exception("Bad resolution. Only values between 1 and 10 are accepted");
					}
										
					estimatedMaze.setResolution(res);
					
					
				}
				catch (Exception ex) {
					GuiUtils.errorMessage(MazeSlammer.this, "Bad map resolution", ex.getMessage());
				}
			}
		});
		
		String curMap = estimatedMaze.getColorMap();
		JMenu colormap = new JMenu("Color map");
		for (String cstr : EstimatedMaze.maps.keySet()) {
			 ButtonGroup cmaps = new ButtonGroup();
			
			JMenuItem item = new JMenuItem(new AbstractAction(cstr) {
				public void actionPerformed(ActionEvent e) {
					estimatedMaze.setColorMap(this.getValue(AbstractAction.NAME).toString());
				}				
			});
			
			cmaps.add(item);
			
			if (cstr.equals(curMap))
				item.setSelected(true);

			colormap.add(item);
		}
		
		options.add(colormap);
		
		menubar.add(options);
		
		setJMenuBar(menubar);
	}
	
	public void stateChanged(EstimatedState state) {
		estimatedMaze.setEstimatedState(state);		
	}
	
	public static void main(String[] args) {
		try
		{
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());			
		}
		catch(Exception e){
		}
		MazeSlammer app = new MazeSlammer();
		app.setIconImage(GuiUtils.getImage("imgs/r2d2.png"));
		app.setSize(800, 500);
		GuiUtils.centerOnScreen(app);
		app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		app.setVisible(true);
	}

	public MazeWalker getClient() {
		return client;
	}
}
